package com.cpu;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author xuan.yang
 * @ClassName CpuBinGenerator
 * @description: TODO
 * @date 2024年03月23日 00:47:35
 * @version: 1.0
 */
public class CpuBinGenerator {
    public static final short A_CS =        1 << 0;         // 0000 0000 0000 0001
    public static final short A_WE =        1 << 1;         // 0000 0000 0000 0010
    public static final short B_CS =        1 << 2;         // 0000 0000 0000 0100
    public static final short B_WE =        1 << 3;         // 0000 0000 0000 1000
    public static final short ALU_OP_SUB =  1 << 4;         // 0000 0000 0001 0000
    public static final short ALU_OP_ADD =       0;         // 0000 0000 0000  0000
    public static final short ALU_EN =      1 << 5;         // 0000 0000 0010 0000
    public static final short C_CS =        1 << 6;         // 0000 0000 0100 0000
    public static final short C_WE =        1 << 7;         // 0000 0000 1000 0000
    public static final short PC_CS =       1 << 8;         // 0000 0001 0000 0000
    public static final short PC_WE =       1 << 9;         // 0000 0010 0000 0000
    public static final short PC_EN =       1 << 10;        // 0000 0100 0000 0000
    public static final short MEM_WE =      1 << 11;        // 0000 1000 0000 0000
    public static final short MEM_CS =      1 << 12;        // 0001 0000 0000 0000
    public static final short STOP =(short)(1 << 15);        // 1000 0000 0000 0000

    public static List<Short> generate() {
        // 1、从第一个内存位置读取数据 并 放入A寄存器
        Short step1 = MEM_CS | A_CS | A_WE | PC_CS | PC_WE | PC_EN;
        // 2、从第二个内存位置读取数据 并 放入B寄存器
        Short step2 = MEM_CS | B_CS | B_WE | PC_CS | PC_WE | PC_EN;
        // 3、（此处需要提前使A、B寄存器同使输出工作）ALU做计算 并 输出 到 C寄存器
        Short step3 = ALU_EN | ALU_OP_ADD | C_CS | C_WE;
        // 4、（此处前提需要CS工作）将C寄存器结果输出 并 将结果输出到 内存
        Short step4 = C_CS | MEM_CS | MEM_WE | PC_WE | PC_CS | PC_EN;
        // 5、停止
        Short step5 = STOP;
        return Stream.of(step1, step2, step3, step4, step5).collect(Collectors.toList());
    }

    public static void main(String[] args) throws IOException {
        BiConsumer<DataOutputStream, Short> fileWriteIntF = (dos, i) -> {
            try {
                System.out.println(String.format("%016X", i).substring(12));
                dos.writeShort(i);
            } catch (IOException e) {
                e.printStackTrace();
            }
        };
        try (DataOutputStream bw = new DataOutputStream(new FileOutputStream("./add.bin"))) {
            generate().forEach(x -> fileWriteIntF.accept(bw, x));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
